/**
 * Created by tanbingqin on 2020/6/8.
 */
import {messages} from "share/common";
import React from 'react'
import { connect } from 'react-redux'
import { Row, Col, Spin, Modal, Button, message, Popover, Affix, Alert } from 'antd'
import withDragDropContext from 'components/with-dnd-context';
import 'styles/components/template/drag-widget-page/drag-widget-page.scss'
import 'styles/setting/expense-type/new-expense-type/expense-type-travel.scss'
import IPhoneX from 'components/iphone-x'
import FakeDropLayout from 'containers/setting/expense-type/new-expense-type/expense-type-travel/drop-source/fake-drop-layout'
import DragWidgetItem from 'containers/setting/expense-type/new-expense-type/expense-type-travel/drag-source/drag-widget-item'
import PhoneContent from 'containers/setting/expense-type/new-expense-type/expense-type-travel/drop-source/phone-content'
import WidgetSetting from 'containers/setting/expense-type/new-expense-type/expense-type-travel/widget-setting'
import expenseTypeTravelService from 'containers/setting/expense-type/new-expense-type/expense-type-travel/expense-type-travel.service'
import processUtil from 'containers/setting/expense-type/new-expense-type/expense-type-travel/process-util'
import errorMessage from 'share/errorMessage'

class ExpenseTypeTravel extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      saving: false,
      form: {}, //表单信息
      normalWidget: [],
      combineWidget: [],
      nowWidget: [],
      nowSelectedIndex: -1,
      subSelectedIndex: -1, //本来没记这个字段的，用的是widget上的subSelectedIndex，因为保存后还在当前页，为了保存后刷新数据时记录上次index
      counter: 0,
    }
  }

  componentWillMount() {
    this.getWidgetList();
  }

  getWidgetList = () => {
    const { expenseTypeOID, setOfBooksId } = this.props.expenseType;
    this.setState({ loading: true });
    Promise.all([
      expenseTypeTravelService.getWidgetList(6010, 2001, expenseTypeOID, setOfBooksId),
      expenseTypeTravelService.getWidgetList(6010, 2002, expenseTypeOID, setOfBooksId)
    ]).then(res => {
      processUtil.processWidgetListData(res[0].data);
      processUtil.processWidgetListData(res[1].data, true);
      this.setState({ normalWidget: res[0].data, combineWidget: res[1].data }, this.initForm);
    }).catch(e => {
      errorMessage(e.response);
      this.setState({loading: false});
    });
  };

  //处理表单详情上的套件数据时，需要根据控件池的套件来处理
  initForm = () => {
    const { expenseTypeOID, setOfBooksId } = this.props.expenseType;
    const { combineWidget, subSelectedIndex } = this.state;
    const { language, languageList } = this.props;
    expenseTypeTravelService.getFormDetail(expenseTypeOID, setOfBooksId || undefined, 2).then(res => {
      let nowWidget = processUtil.initNowWidget(res.data.customFormFields, combineWidget, languageList, language);
      //保存后，保留当前位置
      if (!isNaN(subSelectedIndex) && subSelectedIndex > -1) {
        nowWidget.forEach(widget => {
          if (widget.isCombine) {
            widget.subSelectedIndex = subSelectedIndex;
          }
        });
      }
      this.setState({nowWidget, counter: nowWidget.length, loading: false, form: res.data});
    }).catch(e => {
      errorMessage(e.response);
      this.setState({loading: false});
    });
  };

  /**
   * phone-content内部排序后的事件
   * @param result 返回的ReactDom，key值为拖拽进入时定义的counterFlag
   */
  handleSort = (result) => {
    let { nowWidget, nowSelectedIndex } = this.state;
    //记录当前选择的counterFlag
    let nowSelectWidgetCounter = nowWidget[nowSelectedIndex].counterFlag;
    let targetIndex = -1;
    let tempWidget = [];
    //根据排序后的key值排序
    result.map(item => {
      nowWidget.map(widget => {
        (widget.counterFlag + '') === item.key && tempWidget.push(widget);
      });
    });
    //寻找之前选择的index
    tempWidget.map((item, index) => {
      if(item.counterFlag === nowSelectWidgetCounter)
        targetIndex = index;
    });
    this.setState({ nowWidget: tempWidget, nowSelectedIndex: targetIndex })
  };

  /**
   * 选择某一组件时的回调
   * @param nowSelectedIndex  列表中的第几个
   * @param subSelectedIndex  套件下的第几个子组件
   * @param widget  对应widget对象
   */
  handleSelectWidget = (nowSelectedIndex, subSelectedIndex, widget) => {
    let { nowWidget } = this.state;
    nowWidget[nowSelectedIndex].subSelectedIndex = subSelectedIndex;
    this.setState({ nowSelectedIndex, nowWidget, subSelectedIndex });
    this.props.handlePutAway(true);
  };

  /**
   * 从列表中把widget拖拽入phone-content时的事件
   * @param widget 拖入的widget
   * @param index 拖入后的index
   */
  handleDrop = (widget, index) => {
    let { nowWidget, counter, combineWidget } = this.state;
    if(widget.maxAmount && !widget.isCombine){
      let count = 0;
      nowWidget.forEach(item => {
        item.messageKey === widget.messageKey && count++;
      });
      if(count >= widget.maxAmount){
        message.error(messages('expense-6.key237',{arg1: widget.maxAmount})/*该控件只能有{arg1}个*/);//该控件只能有${widget.maxAmount}个
        return ;
      }
    }
    let suiteKeyList = combineWidget.map(item => item.messageKey);
    if (widget.isCombine && nowWidget.filter(item => suiteKeyList.indexOf(item.messageKey) > -1).length) {
      message.error(messages('expense-6.key238')/*默认套件仅支持添加1个*/);
      return ;
    }
    let tempWidget = JSON.parse(JSON.stringify(widget));
    //因为ListSort根据key值排序，key值不能改变和重复，所以此处给每一个拖拽进入的组件一个counter计数为counterFlag
    tempWidget.counterFlag = counter++;
    tempWidget.isNew = true; //标记是否是新拖入的
    tempWidget.subSelectedIndex = tempWidget.isCombine ? 0 : undefined;
    nowWidget.splice(index, 0, tempWidget);
    this.setState({ nowWidget, counter, nowSelectedIndex: index, subSelectedIndex: tempWidget.subSelectedIndex });
    this.props.handlePutAway(true);
  };

  /**
   * phone-content内部删除后的事件
   * @param index 待删除的索引
   */
  handleDelete = (index) => {
    let { nowWidget, nowSelectedIndex } = this.state;
    Modal.confirm({
      title: messages('expense-6.key131')/*你确定要删除这个组件吗?*/,//你确定要删除这个组件吗?
      content: messages('expense-6.key239')/*配置项将不会保存*/,//配置项将不会保存
      okType: 'danger',
      okText: messages('common.delete')/*删除*/,//删除
      cancelText: messages('common.cancel')/*取消*/,//取消
      onOk: () => {
        nowWidget.splice(index, 1);
        nowSelectedIndex = -1;
        this.setState({ nowWidget, nowSelectedIndex });
      }
    });
  };

  /**
   * 更改widget属性的回调
   * @param widget
   */
  handleChangeWidget = (widget) => {
    const { nowWidget, nowSelectedIndex } = this.state;
    nowWidget[nowSelectedIndex] = widget;
    this.setState({ nowWidget });
  };

  validateData = () => {
    let { nowWidget } = this.state;
    let isOk = true;
    let errorIndex = -1;
    let subErrorIndex = -1;
    let errorMsg = '';
    if (!nowWidget || !nowWidget.length) {
      message.error(messages('expense-6.key240')/*控件数量不能为0*/);
      return;
    }
    nowWidget.forEach((widget, index) => {
      if (widget.isCombine) {
        widget.subWidgetList.forEach((subWidget, subIndex) => {
          if (!processUtil.validateFieldName(subWidget)) {
            errorMsg = messages('expense-6.key241')/*标题不能为空*/;
            errorIndex = index;
            subErrorIndex = subIndex;
            isOk = false;
          }
        });
      } else {
        if (!processUtil.validateFieldName(widget)) {
          errorMsg = messages('expense-6.key241')/*标题不能为空*/;
          errorIndex = index;
          isOk = false;
        }
        if (widget.messageKey === 'com_value_list' && !widget.dataSource) {
          errorMsg = `${widget.fieldName}${messages('expense-6.key242')/*选择列表不能为空*/}`;
          errorIndex = index;
          isOk = false;
        }
      }
    });

    if (!isOk) {
      message.error(errorMsg);
      if (nowWidget[errorIndex].isCombine) {
        nowWidget[errorIndex].subSelectedIndex = subErrorIndex;
      }
      this.setState({nowWidget, nowSelectedIndex: errorIndex, subSelectedIndex: subErrorIndex});
    }
    return isOk;
  };

  processFormData = () => {
    const { nowWidget } = this.state;
    let customFormFields = JSON.parse(JSON.stringify(nowWidget));
    //step0 系统控件的guiWidgetOID置空，子组件的guiWidgetOID和套件的guiWidgetOID一致
    let suiteIndex = -1;
    let subWidgetList = [];
    customFormFields.forEach((widget, index) => {
      if (widget.isCombine) {
        let suiteGuiWidgetOID = widget.guiWidgetOID;
        widget.subWidgetList.forEach(subWidget => {
          subWidget.guiWidgetOID = suiteGuiWidgetOID;
        });
        suiteIndex = index;
        subWidgetList = widget.subWidgetList;
      } else {
        widget.guiWidgetOID = '';
      }
    });
    //step1 把套件子组件拼出来
    suiteIndex > -1 && customFormFields.splice(suiteIndex, 1, ...subWidgetList);
    //step2 把组合控件分开
    customFormFields = processUtil.splitStartEndDate(customFormFields, false);
    customFormFields = processUtil.splitStartEndDate(customFormFields, true);
    //step3 拼多语言
    //step4 处理必填，启用，只读内外一致，本来widget-setting里控制了一起改变来保持一致，但是不启用的后台会删除控件，重新从控件池初始化的是缺少字段的

    customFormFields.forEach((widget, index) => {
      if (!widget.i18n) {
        widget.i18n = {};
      }
      if (widget.fieldNameI18n) {
        widget.i18n.fieldName = processUtil.processLanguageToUpperCase(widget.fieldNameI18n);
      }
      if (widget.promptInfoI18n) {
        widget.i18n.promptInfo = processUtil.processLanguageToUpperCase(widget.promptInfoI18n);
      }
      widget.sequence = index;

      //提示文字控件没有标题，要置空，不然无法通过后台的重复标题校验
      if (widget.messageKey === 'com_prompt_text') {
        widget.fieldName = '';
      }
      if (widget.fieldConstraint) {
        let config = JSON.parse(widget.fieldConstraint) || {};
        //处理启用
        if (config.show) {
          widget.valid = config.show.value;
        }
        //处理必填
        if (config.require) {
          widget.required = config.require.value;
        }
        //处理只读
        if (config.isReadOnly) {
          widget.isReadOnly = config.isReadOnly.value;
        }
      }
    });
    return customFormFields;
  };

  handleSave = () => {
    const { setOfBooksId } = this.props.expenseType;
    let { form } = this.state;
    if (!this.validateData()) {
      return;
    }
    form.customFormFields = this.processFormData();
    this.setState({saving: true});
    expenseTypeTravelService.saveForm(setOfBooksId, 2, form).then(res => {
      message.success(messages('common.operate.success')/*操作成功*/);
      this.setState({ saving: false, nowWidget: [], loading: true }, this.initForm);
    }).catch(err => {
      this.setState({saving: false});
      errorMessage(err.response);
    });
  };

  goBack = () => {
    window.history.go(-1);
  };

  render() {
    const { expenseType, putAway } = this.props;
    const { loading, saving, normalWidget, combineWidget, nowWidget, nowSelectedIndex } = this.state;
    return (
      <div className="right-con-content has-footer">
        <div className="drag-widget-page expense-type-travel">
          {loading ? <Spin/> : (
            <div style={{height: '100%'}}>
              <FakeDropLayout />
              <Row gutter={40} style={{height: '100%'}}>
                <Col span={putAway ? 7 : 9} style={{height: '100%'}}>
                  <div className="widget-area" style={{height: '100%'}}>
                    <Alert
                      style={{marginBottom: 12}}
                      message={messages('expense-6.key326')/*此页面设置当前仅适用于新版差旅申请单*/}
                      type="info"
                      showIcon
                    />
                    <div className="widget-category">{messages('expense-6.key243')/*系统控件*/}</div>
                    <div className="widget-list">
                      {normalWidget.map(widget => <DragWidgetItem widget={widget} key={widget.messageKey}/>)}
                    </div>
                    {/*补贴类型费用没有套件可配*/}
                    {expenseType.subsidyType !== 1 && (
                      <div>
                        <div className="widget-category">{messages('expense-6.key244')/*默认套件*/}</div>
                        <div className="widget-list">
                          {combineWidget.map(widget => <DragWidgetItem widget={widget} key={widget.messageKey}/>)}
                        </div>
                      </div>
                    )}
                  </div>
                </Col>
                <Col span={putAway ? 9 : 15} style={{height: '100%'}} className="widgets-col-wrap">
                  <div className="widgets-con-wrap">
                    <div className='widgets-con'>
                      <div className='widgets-con-header'>
                        <p className='second-title header-title'>{expenseType.name}</p>
                      </div>
                      <div className='scroll-con-wrap'>
                        <PhoneContent
                          widgetList={nowWidget}
                          onSort={this.handleSort}
                          nowSelectedIndex={nowSelectedIndex}
                          onDelete={this.handleDelete}
                          onSelect={this.handleSelectWidget}
                          onDrop={this.handleDrop}
                        />
                      </div>
                      <div className='left-split'></div>
                      <div className='right-split'></div>
                    </div>
                  </div>
                </Col>
                {putAway && (
                  <Col span={8} style={{height: '100%'}}>
                    <div style={{height: '100%', paddingRight: '20px'}}>
                      <WidgetSetting
                        widget={nowWidget[nowSelectedIndex] || {}}
                        nowWidgetList={nowWidget}
                        valueKey="counterFlag"
                        widgetList={normalWidget.concat(combineWidget)}
                        onChange={this.handleChangeWidget}
                      />
                    </div>
                  </Col>
                )}
              </Row>
            </div>
          )}
        </div>
        <div className="page-footer">
          <Button type="primary" style={{marginRight: 8}} loading={saving} onClick={this.handleSave}>{messages('common.save')/*保存*/}</Button>
        </div>
      </div>
    )
  }
}

ExpenseTypeTravel.propTypes = {
  expenseType: React.PropTypes.object,
};

function mapStateToProps(state) {
  return {
    language: state.main.language,
    languageList: state.login.languageList,
    user: state.login.user
  }
}

export default connect(mapStateToProps)(withDragDropContext(ExpenseTypeTravel))

